<template>
  <div style="height: 100%">
    <el-table class="ELtable" ref="tableRef" :data="tableData" style="width: 100%;height:100%;" :row-key="getRowKey"
      @selection-change="changeSelect" :key="key">
      <el-table-column type="index" width="50" align="center" />
      <el-table-column label="" width="30" v-if="editor === true">
        <template #default="{ row }">
          <el-icon style="cursor: move;" v-if="row.keyName || row.keyValue">
            <Operation class="drag-handle" />
          </el-icon>
        </template>
      </el-table-column>
      <el-table-column type="selection" width="30" v-if="editor === true" />
      <el-table-column prop="keyName" label="参数名称">
        <template #default="{ row }">
          <el-autocomplete v-if="editor === true" v-model="row.keyName" :fetch-suggestions="querySearch"
            class="inline-input" placeholder="" @change="(val) => handleChangeValue(val, row)"
            @select="(val) => selectSuggestion(val, row)" />
        </template>
      </el-table-column>
      <el-table-column prop="keyValue" label="参数值">
        <template #default="{ row }">
          <div class="input-wrap" v-if="editor === true">
            <template v-if="row.keyType != 'file'">
              <el-autocomplete v-if="editor === true" v-model="row.keyValue" :fetch-suggestions="querySearchVal"
                class="inline-input" placeholder="" @change="(val) => handleChangeValue(val, row)"
                @select="(val) => selectSuggestion(val, row)"
                :class="{ 'var-color': row.keyValue.indexOf && row.keyValue.indexOf('\{{') != -1 }" />
              <el-icon class="array-icon" @click="handleValueMultipleEditor(row)"
                v-if="row.keyValue.indexOf && row.keyValue?.indexOf('\{{') == -1">
                <Rank />
              </el-icon>
            </template>
            <el-upload v-if="row.keyType == 'file'" multiple v-model:file-list="fileList" class="upload-demo" action=""
              :on-preview="handlePreview" :on-remove="handleRemove" :before-remove="beforeRemove" :limit="3"
              :on-exceed="handleExceed">
              <el-button type="primary" plain size="small">
                Upload<el-icon class="el-icon--right">
                  <Upload />
                </el-icon>
              </el-button>
            </el-upload>
          </div>
        </template>
      </el-table-column>
      <el-table-column prop="keyType" label="类型">
        <template #default="{ row }">
          <div class="input-wrap" v-if="editor === true">
            <el-select v-model="row.keyType" @change="(val) => handleChangeValue(val, row)">
              <el-option label="string" value="string" />
              <el-option label="integer" value="integer" />
              <el-option label="boolean" value="boolean" />
              <el-option label="number" value="number" />
              <el-option label="object" value="object" />
              <el-option label="array" value="array" />
              <!-- <el-option label="file" value="file" /> -->
            </el-select>
          </div>
        </template>
      </el-table-column>
      <el-table-column prop="keyDesc" label="说明">
        <template #default="{ row }">
          <el-input v-model="row.keyDesc" v-if="editor === true" @change="(val) => handleChangeValue(val, row)">
            <template #suffix>
              <el-icon style="cursor:pointer" @click="openMarkdown(row)">
                <FullScreen />
              </el-icon>
            </template>
          </el-input>
          <v-md-preview v-else :text="row.keyDesc" />
        </template>
      </el-table-column>
      <el-table-column prop="enable" label="是否必需" align="center" v-if="isenable === true">
        <template #default="{ row }">
          <el-checkbox v-model="row.enable" :disabled="editor === false"
            @change="(val) => handleChangeValue(val, row)" />
        </template>
      </el-table-column>
      <el-table-column width="80" align="center" v-if="editor === true">
        <template #header>
          <span style="color:#409eff;cursor: pointer;" @click="handleMultipleEdit">批量编辑</span>
        </template>
        <template #default="{ row }">
          <el-button link @click="removeRow(row)" v-if="tableData.length > 1">
            <el-icon>
              <Remove />
            </el-icon>
          </el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
  <multipleEdit ref="multipleEditRef" :editorValue="editorValue" @update-editor-value="updateEditorValue"
    :isShowText="false" />
  <markdownDialog ref="markdownDialogRef" :data="keyDescValue" @markdown-value="handleMarkdownValue" />
</template>

<script setup lang="ts">
import { Remove, Operation } from '@element-plus/icons-vue'
import Sortable from "sortablejs"
import { ElMessage, ElMessageBox } from 'element-plus'
import { Upload, Rank } from '@element-plus/icons-vue'
import { propTypes } from '@/utils/propTypes'
import multipleEdit from '../debug/dialog/MultipleEdit.vue'
import { useDebugStore } from '@/store/modules/debug'
import { FullScreen } from '@element-plus/icons-vue'
import markdownDialog from './markdownDialog.vue'
const environmentVars = computed(() => debugStore.getEnvironmentVars)
const debugStore = useDebugStore()
let selectedTableData = ref([] as any)
const tableData = ref([
  { id: 1, keyName: '', keyValue: '', keyType: '', keyDesc: '', enable: false }
] as any)
let id = 1000
const tableRef = ref()
const key = ref(0)
/** 变量名称提示集合 */
const suggestions = computed(() => {
  return environmentVars.value.map(item => {
    return {
      value: item.varName
    }
  })
})
/** 变量值提示集合 */
const suggestionsVal = computed(() => {
  return environmentVars.value.map(item => {
    return {
      value: `{{${item.varName}}}`
    }
  })
})
const emit = defineEmits(['changeEditMethod', 'selectedTableData', 'allTableData']) // 定义 success 事件，用于操作成功后的回调
const props = defineProps({
  data: {
    default: () => [] as any
  },
  editor: propTypes.bool.def(),
  isenable: propTypes.bool.def(false)
})
const multipleEditRef = ref()
const editorValue = ref("")
const currentMultipleEditorRow = ref()
watch(() => props.data,
  () => {
    // 批量编辑后更新表格数据并处理选中
    if (props.data && props.data.length) {
      tableData.value = props.data.map((item, index) => {
        return {
          ...item,
          keyValue: item.keyValue || '',
          id: index + 1
        }
      })
      nextTick(() => {
        tableData.value.forEach(item => {
          if (item.keyName || item.keyValue) {
            tableRef.value.toggleRowSelection(item, true)
          } else {
            tableRef.value.toggleRowSelection(item, false)
          }
        })
        handleChangeValue()
      })
    } else {
      tableData.value = [{ id: 1, keyName: '', keyValue: '', keyType: '', keyDesc: '', enable: false }]
    }
    key.value++
  }, {
  deep: true
})
/**
 * 点击value批量输入按钮后弹窗
 * */
const handleValueMultipleEditor = (row) => {
  currentMultipleEditorRow.value = row
  editorValue.value = row.keyValue
  multipleEditRef.value.open()
}
/**
 * editor 弹窗值输入完成确定后
 * */
const updateEditorValue = (data) => {
  tableData.value.forEach(item => {
    if (item.id == currentMultipleEditorRow.value.id) {
      item.keyValue = data
    }
  })
}
/**
 * 表单内容变化时自动增加一行
 * */
const handleChangeValue = (val?, row?) => {
  // keyType赋默认值
  row && (row.keyType = row.keyType || 'string')
  updateSelectData()
  // 是否向下添加一行判断
  const isAllNull = tableData.value.some(k => {
    if (!k.keyName && !k.keyValue && !k.keyType) {
      return true
    }
    return false
  })
  // 添加一行并选中
  if (!isAllNull) {
    tableData.value.push({ id: ++id, keyName: '', keyValue: '', keyType: '', keyDesc: '', enable: false })
    tableData.value.forEach(item => {
      if (item.keyName || item.keyValue) {
        tableRef.value.toggleRowSelection(item, true)
      } else {
        tableRef.value.toggleRowSelection(item, false)
      }
    })
  }
}
/**
 * 表格数据变化时，更新选中数据
 * */
const updateSelectData = () => {
  selectedTableData.value = tableRef.value.getSelectionRows()
  selectedTableData.value.forEach(item => {
    const current = tableData.value.find(k => k.id == item.id)
    if (current) {
      item.id = current.id
      item.keyName = current.keyName
      item.keyValue = current.keyValue
      item.keyType = current.keyType
      item.keyDesc = current.keyDesc
      item.enable = current.enable
    }
  })
  emit('selectedTableData', selectedTableData.value)
}
/**
 * 选中时触发
 * */
const changeSelect = () => {
  selectedTableData.value = tableRef.value.getSelectionRows()
  emit('selectedTableData', selectedTableData.value)
}
/**
 * 行拖拽
 * */
const rowDrop = () => {
  const tbody = document.querySelector(".ELtable tbody");
  Sortable.create(tbody, {
    animation: 150, //动画参数
    handle: '.drag-handle',
    onEnd({ newIndex, oldIndex }) {
      const currRow = tableData.value.splice(oldIndex, 1)[0]
      tableData.value.splice(newIndex, 0, currRow)
    },
  });
};
/**
 * 获取表格每行的key
 * */
const getRowKey = (row) => {
  return row.id;
}

/**
 * 选择建议
 * */
const selectSuggestion = (val, row?) => {
  // 选择变量名称后，自动补全变量值
  if (val.value.indexOf('{{') == -1) {
    const localValue = environmentVars.value.find(e => e.varName == val.value).varName
    row.keyValue = `{{${localValue}}}`
  }
  handleChangeValue(val, row)
}
/**
 * 移除一行
 * */
const removeRow = (row) => {
  tableData.value.splice(tableData.value.indexOf(row), 1);
}

/**
 * 点击批量编辑，弹窗
 * */
const handleMultipleEdit = () => {
  emit('changeEditMethod', tableData.value)
}
const fileList = ref([])

/**文件删除*/
const handleRemove = (file, uploadFiles) => {
  console.log(file, uploadFiles)
}

/**文件预览*/
const handlePreview = (uploadFile) => {
  console.log(uploadFile)
}
/**文件*/
const handleExceed = (files, uploadFiles) => {
  ElMessage.warning(
    `The limit is 3, you selected ${files.length} files this time, add up to ${files.length + uploadFiles.length
    } totally`
  )
}
/**文件删除*/
const beforeRemove = (uploadFile, uploadFiles) => {
  return ElMessageBox.confirm(
    `Cancel the transfer of ${uploadFile.name} ?`
  ).then(
    () => true,
    () => false
  )
}
/**建议过滤*/
const querySearch = (queryString: string, cb: any) => {
  const results = queryString
    ? suggestions.value.filter(createFilter(queryString))
    : suggestions.value
  // call callback function to return suggestions
  cb(results)
}
const querySearchVal = (queryString: string, cb: any) => {
  const results = queryString
    ? suggestionsVal.value.filter(createFilter(queryString))
    : suggestionsVal.value
  // call callback function to return suggestions
  cb(results)
}
const createFilter = (queryString: string) => {
  return (restaurant) => {
    return (
      restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
    )
  }
}
const markdownDialogRef = ref()
const keyDescValue = ref('')
const openMarkdown = (row) => {
  currentMultipleEditorRow.value = row
  keyDescValue.value = row.keyDesc
  markdownDialogRef.value.open()
}
const handleMarkdownValue = (data) => {
  tableData.value.forEach(item => {
    if (item.id == currentMultipleEditorRow.value.id) {
      item.keyDesc = JSON.parse(JSON.stringify(data.value))
    }
  })
  handleChangeValue()
}

onMounted(() => {
  nextTick(() => {
    rowDrop();
    tableData.value.forEach(item => {
      if (item.keyName || item.keyValue) {
        tableRef.value && tableRef.value.toggleRowSelection(item, true)
      } else {
        tableRef.value && tableRef.value.toggleRowSelection(item, false)
      }
    })
  })
});
</script>

<style scoped>
:deep(.el-table__inner-wrapper::before) {
  height: 0;
}

:deep(th.el-table__cell) {
  font-weight: 400;
  /* color: #000; */
}

:deep(.var-color .el-input__inner) {
  color: rgb(216, 200, 13);
}

.input-wrap {
  position: relative;

  &:hover {
    .array-icon {
      display: block;
    }
  }

  :deep(.upload-demo) {
    position: relative;
    top: 5px;
  }
}

.array-icon {
  position: absolute;
  top: 8px;
  right: 5px;
  display: none;
}


.suggestion-ul {
  list-style: none;
  padding: 0;
  margin: 0;
  line-height: 25px;
}

.hide {
  display: flex;
  width: 100%;
  height: 0;
  line-height: 0;
}

:deep(.el-input__wrapper),
:deep(.el-select__wrapper) {
  box-shadow: none;
  border-radius: 0;
  margin-left: -10px;
}

:deep(.el-table__body tr > td:hover) {

  /* :deep(.el-input__wrapper), */
  /* :deep(.el-select__wrapper) { */
  /* box-shadow: 0 0 0 1px #888 inset; */
  /* } */
}

:deep(.el-table__body tr:hover > td) {
  background-color: transparent !important;
  /* 移除背景颜色 */
}

:deep(.el-table__body tr > td) {
  height: 32px;
  line-height: 32px;
  padding: 0;

  .cell {
    padding: 0;
  }
}

:deep(.github-markdown-body) {
  padding: 0 !important;
  font-size: 14px !important;
}
</style>
